package com.monolithiot.huawei.api.impl;

import com.alibaba.fastjson.JSON;
import com.monolithiot.huawei.api.ApiClient;
import com.monolithiot.huawei.util.HttpUtils;
import com.monolithiot.huawei.vo.TokenResponseBody;
import com.monolithiot.huawei.vo.WeightRequestBody;
import com.monolithiot.huawei.vo.WeightResponseBody;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.message.BasicHeader;

import java.io.IOException;
import java.util.*;

/**
 * 2019/1/9 Create by 郭文梁
 * HuaWeiApiClientImpl
 * 华为API客户端实现
 *
 * @author 郭文梁
 * @date 2019/1/9
 */
public class HuaWeiApiClientImpl implements ApiClient {
    private static final String DEFAULT_TOKEN_TYPE = "Bearer";
    private static final String CONTENT_TYPE_JSON = "application/json;charset=utf-8";
    private static final String AUTHORIZATION_HEADER_NAME = "Authorization";
    private static final String AUTHORIZATION_HEADER_VALUE_TEMPLATE = "%s %s";
    private static final String GET_TOKEN_REQUEST_BODY = "grant_type=client_credentials";
    private static final String UPDATE_LPN_WEIGHT_VOLUME_URL = "https://api-beta.huawei.com:443/service/weightVolumnInput/updateLpnWeightVolumn/1.0.0";
    private static final String GET_TOKEN_URL = "https://api-beta.huawei.com:443/oauth2/token";
    private static final Map<String, String> TOKEN_TYPE_MAP;

    static {
        TOKEN_TYPE_MAP = new HashMap<>(2);
        TOKEN_TYPE_MAP.put("bearer", DEFAULT_TOKEN_TYPE);
    }

    private String tokenAuthorizationBase64;

    public HuaWeiApiClientImpl(String apiKey, String apiSecret) {
        tokenAuthorizationBase64 = "Basic " + asBase64Authorization(apiKey, apiSecret);
    }

    @Override
    public TokenResponseBody getToken() throws IOException {
        List<Header> headers = new ArrayList<>();
        headers.add(new BasicHeader(AUTHORIZATION_HEADER_NAME, tokenAuthorizationBase64));
        headers.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded"));
        String response = HttpUtils.post(GET_TOKEN_URL, headers, GET_TOKEN_REQUEST_BODY);
        if (response == null) {
            return null;
        }
        TokenResponseBody responseBody = JSON.parseObject(response, TokenResponseBody.class);
        if (responseBody != null) {
            responseBody.setCreateTime(new Date());
        }
        return responseBody;
    }

    @Override
    public WeightResponseBody updateLpnWeightVolume(WeightRequestBody requestBody, TokenResponseBody token) throws IOException {
        String tokenType = TOKEN_TYPE_MAP.getOrDefault(token.getTokenType(), DEFAULT_TOKEN_TYPE);
        String authorizationHeaderValue = String.format(AUTHORIZATION_HEADER_VALUE_TEMPLATE, tokenType, token.getAccessToken());
        List<Header> headers = new ArrayList<>();
        headers.add(new BasicHeader(AUTHORIZATION_HEADER_NAME, authorizationHeaderValue));
        headers.add(new BasicHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_JSON));

        String body = requestBody.toJSON();
        String response = HttpUtils.post(UPDATE_LPN_WEIGHT_VOLUME_URL, headers, body);
        if (response == null) {
            return null;
        }
        return JSON.parseObject(response, WeightResponseBody.class);
    }

    /**
     * 对key和Secret进行Base64编码
     * 应华为要求，编码方式为base64(key + ":" + secret)
     *
     * @param key    APIKey
     * @param secret APISecret
     * @return base64 String
     */
    private String asBase64Authorization(String key, String secret) {
        return Base64.getEncoder().encodeToString((key + ":" + secret).getBytes());
    }
}
